This short tutorial presents a simple "Hello World" program for the WaveShare EX-F320, either the premium version (which includes the DVK501) or the standard version with an extra RS232 board. The author used a Debian GNU/Linux system, but the tutorial should work for other Linux distributions, *BSD or other Unices.
The tools we use are
The C8051F340/380 board is connected to the host computer via a U-EC6 for power and to write the demo onto the board. Depending on wether we use the premium version or the standard version with RS232 board, the communication setup is different: For the EX-F320 Premium we connect the DVK501 board via the BUS-B connector, which will do for both data and power; the serial cable is then connected to the UART0 header of the DVK501. For the EX-F320 Standard with RS232 board, we connect the RS232 board to the PD5 and PD6 headers for data (TxIN to P0.4, RxOUT to P0.5) and to the power header for power (VCC to +5V, GND to GND); the serial cable is then attached to the RS232 board.
Depending on your operating system there might be an easy way to install SDCC 3.5.0 or newer using a package system or similar (e.g. apt-get install sdcc on Debian). While SDCC 3.4.0 should be sufficient for this tutorial, you might want to try a newer version in case you encounter any bugs.
SDCC binaries or a source tarball can be downloaded from its website.
ec2writeflash is part of the ec2-new package.
The ec2-new source can be found at its GitHub location, where there is also a download link for a zip archive of the sources. To compile it, a C compiler, such as gcc, autotools and some necessary libraries need to be installed. Unzip the archive (e.g. using unzip stm8flash-master.zip) change into the directory stm8flash-master and type autoreconf; automake --add-missing; libtoolize; autoreconf; ./configure && make
. In case there are any errors, such as header files not found, check that all necessary libraries are installed.
We present a simple Demo that repeatedly outputs "Hello World!" Here is the C code:
// Source code under CC0 1.0 #include <stdio.h> __sfr __at(0xe1) XBR0; __sfr __at(0xe2) XBR1; __sfr __at(0xa4) P0MDOUT; __sfr __at(0xd9) PCA0MD; __sfr __at(0x88) TCON; __sfr __at(0x89) TMOD; __sfr __at(0x8b) TL1; __sfr __at(0x8d) TH1; __sfr __at(0x98) SCON0; __sfr __at(0x99) SBUF0; #if __SDCC_REVISION >= 9624 int putchar(int c) #else void putchar(char c) #endif { while(!(SCON0 & 0x02)); SCON0 &= ~0x02; SBUF0 = c; #if __SDCC_REVISION >= 9624 return(c); #endif } unsigned char _sdcc_external_startup(void) { PCA0MD = 0; // Disable watchdog timer return 0; // perform normal initialization } void main(void) { unsigned long int i = 0; // Initialize I/O pins P0MDOUT = 0x10; // Set port P0.4 (Uart tx) to push-pull XBR0 = 0x01; // UART0 on P0.4 and P0.5 XBR1 = 0x40; // Enable push/pull for Tx // Configure UART for 4800 baud, 8 data bits, 1 stop bit. TMOD = 0x20; SCON0 = 0x40; TH1 = 243; TCON |= 0x40; SCON0 |= 0x02; // Tell putchar() the UART is ready to send. for(;;) { printf("Hello World!\n"); for(i = 0; i < 147456; i++); // Sleep } }
SDCC is a freestanding, not a hosted implemenatation of C, and allows main to return void. In SDCC up to SDCC 3.6.0 putchar()
used to return void
. This is not standard compliant and was changed to int
in current SDCC versions. The printf()
from the standard library uses putchar()
for output. Since putchar()
is device-specific we need to supply it. In this case we want it to output data using UART0.
The demo can be compiled simply by invocing sdcc using sdcc -mmcs51 --std-c99 serial.c
assuming the C code is in led.c. The option -mmcs51
selects the target port (mcs51). An .ihx file with a name corresponding to the source file will be generated.
Assuming the board is connected to a U_EC6 attached via USB, ec2writeflash --port USB --hex serial.ihx --run
will write the demo onto the board. You can see the "Hello world" by attaching a serial cable to the DB9 connector on the RS232 board, and using a terminal program configured for 4800 baud, no parity, 8 bits, 1 stop bit and no flow control.
ec2writeflash is part of ec2drv once written by Ricky White. Since ec2drv is no longer maintained, we use the version from the ec2-new fork.
SDCC was initially written by Sandeep Dutta for the MCS-51, and has a relatively conservative architecture (see Sandeep Dutta, "Anatomy of a Compiler", 2000). It has been extended by various contributors and more recently, incorporated some cutting-edge technologies, in particular in register allocation (see Philipp Klaus Krause, "Optimal Register Allocation in Polynomial Time", 2013 and "Bytewise Register Allocation", 2015). However the mcs51 backend does not have all the fancy features and optimizations that some newer backends have.
SDCC is a C compiler that aims to be compliant with the C standards.
Important compiler options for MCS-51 developers include:
-c
to compile into object files to be linked later--std-c99
for compilation in C99 mode (some C99 features, e.g. variable-length arrays are not yet supported in sdcc though)--model-large
to use the xram for variables by default